Call Stack v Runtime

Otázka od: Jan Rizek

23. 9. 2004 17:18

Mam aplikaci, kde, kdyz dojde k chybe, tak se zobrazi okno s Call Stackem a
uzivatel ho muze odeslat me. Takze vim, kdy k chybe doslo. Kdyz to zkousim z
Delph, je vse OK. Ovsem, kdyz projekt zkompiluju a pustim u uzivatele, tak tam
Call Stack neni. Pritom u me na pocitaci je - jsem z toho trochu zmaten   Je
na to nejake zaskrtavatko, zda kompilovat do EXE i Call Stack informace?

Proc nekdy je Call Stack uplne nic nerikajici - jen nazev aplikace a adresa
chyby a nekdy jsou tam i informace o Unitach..  


Odpovedá: Jiri Cincura

23. 9. 2004 17:28

Jan Rizek wrote:
> Proc nekdy je Call Stack uplne nic nerikajici - jen nazev aplikace a
> adresa chyby a nekdy jsou tam i informace o Unitach..  

Zalezi na tom, kde chyba vznikla. Pokud bude v Button1.Click, budes tam mit,
kde se to stalo.

Ale treba pokud mas nekde nadefinovano OnTerminate proceduru pro TThread,
ale ten objekt, kam se ma odkazuje procedure je uz davno ulvolneny, skoci ti
jen AV, ale tezko ti to rekne kde.

--
Jiri Cincura
e-mail: mailto:jiri@cincura.net; mailto:xcincura@informatics.muni.cz
ICQ: 314711544
web: http://www.cincura.net; http://photo.cincura.net



Odpovedá: Daniel Frantik

24. 9. 2004 8:13

Ahoj,
  chyba bude nejspis v tom, ze tam nemas *.map soubor. Tento je potreba
distibuovat spolu s aplikaci nebo v pripade pouziti funkci z JCL (vypis
stacku apod) lze nejakym udelatkem (taky z JCL) prilinkovat k *.exe aplikace

Danik
> -----Original Message-----
> Jan Rizek wrote:
> > Proc nekdy je Call Stack uplne nic nerikajici - jen nazev aplikace a
> > adresa chyby a nekdy jsou tam i informace o Unitach..  


Odpovedá: Petr Kuklik

24. 9. 2004 8:57

Ahoj,
  mohl by me nezkuseneho nekdo zasvetit do tohoto tematu? Jan Rizek psal, ze
pri chybe zobrazuje v aplikaci Call Stack. Jak se toho da dosahnout? Lze tak
udelat samostatnymi prostredky Delphi nebo musim pouzit JCL?

Diky Petr


>>> "Daniel Frantik" <frantik@telpro.cz> 24.9.2004 9:13:45 >>>
Ahoj,
  chyba bude nejspis v tom, ze tam nemas *.map soubor. Tento je potreba
distibuovat spolu s aplikaci nebo v pripade pouziti funkci z JCL (vypis
stacku apod) lze nejakym udelatkem (taky z JCL) prilinkovat k *.exe aplikace

Danik
> -----Original Message-----
> Jan Rizek wrote:
> > Proc nekdy je Call Stack uplne nic nerikajici - jen nazev aplikace a
> > adresa chyby a nekdy jsou tam i informace o Unitach..  



Odpovedá: Jiri Cincura

24. 9. 2004 8:36

Daniel Frantik wrote:
> Ahoj,
> chyba bude nejspis v tom, ze tam nemas *.map soubor. Tento je potreba
> distibuovat spolu s aplikaci nebo v pripade pouziti funkci z JCL (vypis
> stacku apod) lze nejakym udelatkem (taky z JCL) prilinkovat k *.exe
> aplikace

jj, to je taky mozny.
Jeste bych dodal, ze je dobre mit Detailed MAP a to udelatko z JCL (pokud
mas korektne "nainstalovany") je v menu Project > zaskrtnout uplne dole
Insert JCL Debug Data.

--
Jiri Cincura
e-mail: mailto:jiri@cincura.net; mailto:xcincura@informatics.muni.cz
ICQ: 314711544
web: http://www.cincura.net; http://photo.cincura.net


Odpovedá: Jan Rizek

24. 9. 2004 12:07

Posilam cast kodu, kde to delam pomoci JCL..

ShowExceptionDialog si musete naklikat sam   K posilani by email - je
uplne dole..

Existuje i jene reseni - v JCL je to jiz hotovo - viz. konference - ja to
delam takto..

*---------

procedure HandleException(E: Exception);
var
  S : TJclStackInfoList;
  i: integer;
  SL: TStringList;
  G: TabxCustomGlobal;
  FullUserName: string;
  ActiveForm : TForm;
  FocusedComponent: TComponent;
  FN, CN, ImageFileName : string;

  P, Z : TPoint;

  {Screen to BMP}
  Image: TImage;
  DC: HDC;
  DesktopWnd: HWND;

  ZipMaster: TZipMaster;

  Delete: boolean;
  Glob : TabxCustomGlobal;
begin

  Glob:= getGlobalNoError;

  if (Glob<>nil) then
    if not Glob.handleException then Exit;

 {logovani chyb}
  S:= JclCreateStackList(true, 0, nil);

  SL:= TStringList.create;
  try
  S.AddToStrings(SL, true, false, true);

  {prvnich 10 je vsude stejnych..}
  for i:= 0 to 9 do SL.Delete(i);

  G:= GetGlobalNoError;
  if G=nil then FullUserName:= '<<??>>'
  else FullUserName:= G.FullUserName;

  {owner formularu je snad vsude Application..
    vsechno jsem nezkontroloval, ale vetsina tak je.. }
  with Application do begin
    ActiveForm:= nil;
    for i:= 0 to ComponentCount-1 do
      if Components[i] is TForm then
        if TForm(Components[i]).Active then begin
          ActiveForm := TForm(Components[i]);
          break;
        end;
  end;

  {To JR: Jak vis, ze nejaky activeForm existuje?}
  { FocusedComponent:= ActiveForm.ActiveControl; dale upraveno}

  FN:='<< none >>';
  CN:= '<< none >>';
  if ActiveForm<>nil then begin
     FN:= ActiveForm.Name;
     if ActiveForm.ActiveControl<>nil then begin
        FocusedComponent:= ActiveForm.ActiveControl;
        CN := FocusedComponent.Name;
     end;
  end;

  Z.X:=0; Z.Y:=0;
  P:= Z;
  if FocusedComponent<>nil then begin
     if FocusedComponent is TControl then
        P:= TControl(FocusedComponent).ClientToScreen(Z);
  end;

  {zpatky z Delph do aplikace..}
  with Application do begin
    ProcessMessages;
    BringToFront;
  end;


  {obrazek obrazovky}
  if not DirExists(ExtractFileDir(Application.ExeName)+'\Errors') then
    CreateDir(ExtractFileDir(Application.ExeName)+'\Errors');

  ImageFileName:= DateToStr(today)+'__'+TimeToStr(Now);
  ImageFileName:= StringReplace(ImageFileName, ':','_', [rfReplaceAll]);
  ImageFileName:= StringReplace(ImageFileName, '.','_', [rfReplaceAll]);
  ImageFileName:=
ExtractFileDir(Application.ExeName)+'\Errors\'+ImageFileName;

  Image:= TImage.create(Application);

  try
    with Image.Picture do begin
      Bitmap.Width := Screen.Width; // nastavY UY?ku bitmapy na UY?ku
screenu
      Bitmap.Height := Screen.Height; // nastavY v?Uku bitmapy na v?Uku
screenu
      DesktopWnd := GetDesktopWindow; // zjiti wokno plochy
      DC := GetWindowDC(DesktopWnd); // zjiti handle wokna plochy
      BitBlt(Bitmap.Canvas.Handle, 0, 0, Screen.Width, Screen.Height,
      GetDC(GetDesktopWindow), 0, 0, SrcCopy);// zkopYruje obsah screenu
pomocY WinApi funkce Bitblt do DesktopBitmap
      ReleaseDC(DesktopWnd, DC); // uvolni DC

      Bitmap.PixelFormat:= pf4bit;

    {tecka}
    with P do begin
      Bitmap.Canvas.Brush.Color:= clRed;
      with Bitmap.Canvas.Pen do begin
        Color:= clRed;
        Width:= 2;
      end;
      Bitmap.Canvas.Ellipse(X-4,Y-4,X+4,Y+4);
    end;

      SaveToFile(ImageFileName+'.bmp');
    end;
  finally
    Image.Free;
  end;

  {zapakuju..}

  ZipMaster:= TZipMaster.create(Application);
  ZipMaster.ZipFileName:= ImageFileName+'.zip';
  ZipMaster.FSpecArgs.Clear;

  ZipMaster.FSpecArgs.Add(ImageFileName+'.bmp');
  ZipMaster.Add;

  {logovani na disk + posilani emailem..}
  ShowExceptionDialog(DateToStr(today)+' '+TimeToStr(now),
    FullUserName, E.Message, E.ClassName, SL.Text,
    FN, CN, ImageFileName, Delete);
  finally
    SL.Free;
    if Delete then begin
      DeleteFile(PChar(ImageFileName+'.bmp'));
      DeleteFile(PChar(ImageFileName+'.zip'));
    end;
  end;

end;

-----
posilani emailu -

{odesle email podle parametru..}
function SendEmail2(Afrom, Ato, Asubject, ASMTPHost, AUserName, APassWord,
AFileName: string; Atext: TStringList): boolean;
var
  m : TMimemess;
  MimeBody : TMimePart;
  group : TSetupGrpConnections;
begin
  m:=TMimemess.create;
  try
    if AFileName<>'' then begin
      MimeBody := M.AddPartMultiPart('mixed', nil);
      m.AddPartText(ATExt, MimeBody);
      m.AddPartBinaryFromFile( AFileName, MimeBody);
    end
    else m.AddPartText(ATExt, nil);
    m.header.from:= AFrom; //'"Jan ?izek" <jan_rizek@centrum.cz>';
    m.header.tolist.add( ATo); //'jan_rizek@centrum.cz');
    m.header.subject:= Asubject; // 'sislat zlu?oueky kuo Z?S Ii';
    m.EncodeMessage;
    Group:=
TSetupGrpConnections(GetGlobalNoError.SetupGroups.GetSetupGroup('Connections
'));
    with Group do
      Result:=SendToRaw(AFrom, ATo, ASMTPhost, m.lines, AUserName,
APassWord);
  finally
    m.free;
  end;
end;

> Ahoj,
> mohl by me nezkuseneho nekdo zasvetit do tohoto tematu? Jan Rizek psal,
ze pri chybe zobrazuje v aplikaci Call Stack. Jak se toho da dosahnout? Lze
tak udelat samostatnymi prostredky Delphi nebo musim pouzit JCL?
>
> Diky Petr


Odpovedá: mstevlik@gamo.sk

24. 9. 2004 12:40

Pozeram ze tu opat rozoberate Call Stack a JCL
Pouzivam to tiez, ale mam jeden problem
Mam app kt. vyuziva MS SQL 2000 a obcas sa u klienta stane nieco take, ze
mu windowsi vyhodia hlasku
"Program provedl neplatnou operacii a bude
ukoncen", bohuzial vtomto pripade
mi JCL nezareaguje, bo nestal exception
v TApplication
Ako mozem zistit kde takato chyba vznikla?
 
Stevlik Marian
ISYS programator

GAMO a.s.
Kyjevske nam. 6
974 04 Banska Bystrica
mail: mstevlik@gamo.sk
tel: +421 48 4137935, 4372111
ip-tel: 421 48 4372098
mobil: +412 905 462010
ICQ: 38493645